home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktimeintro / makeeffectmovie / start code / application files / comapplication.c next >
Encoding:
Text File  |  2000-10-06  |  15.3 KB  |  599 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //
  7. //    Written by:    Tim Monroe
  8. //                Based on the QTShell code written by Tim Monroe, which in turn was based on the MovieShell
  9. //                code written by Kent Sandvik (Apple DTS). This current version is now very far removed from
  10. //                MovieShell.
  11. //
  12. //    Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  13. //
  14. //    Change History (most recent first):
  15. //       
  16. //       <2>         03/20/00    rtm        made changes to get things running under CarbonLib
  17. //       <1>         11/05/99    rtm        first file
  18. //
  19. //////////
  20.  
  21. //////////
  22. //
  23. // header files
  24. //
  25. //////////
  26.  
  27. #include "ComApplication.h"
  28. #include "MakeEffectMovie.h"
  29.  
  30.  
  31. //////////
  32. //
  33. // global variables
  34. //
  35. //////////
  36.  
  37. // external variables
  38. extern QTParameterDialog    gEffectsDialog;
  39. extern Boolean                gCopyMovieMedia;                    // should we copy the movie media into the new effects movie?
  40.  
  41. #if TARGET_OS_MAC
  42. AEEventHandlerUPP        gHandleOpenAppAEUPP;                    // UPPs for our Apple event handlers
  43. AEEventHandlerUPP        gHandleOpenDocAEUPP;
  44. AEEventHandlerUPP        gHandlePrintDocAEUPP;
  45. AEEventHandlerUPP        gHandleQuitAppAEUPP;
  46. extern Boolean            gAppInForeground;                        // is our application in the foreground?    
  47. #endif
  48.  
  49. #if TARGET_OS_WIN32
  50. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  51. #endif
  52.  
  53.  
  54. //////////
  55. //
  56. // QTApp_Init
  57. // Do any application-specific initialization.
  58. //
  59. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  60. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  61. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  62. //
  63. //////////
  64.  
  65. void QTApp_Init (UInt32 theStartPhase)
  66. {
  67.     // do any start-up activities that should occur before the MDI frame window is created
  68.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  69.  
  70.         // check to make sure that QuickTime video effects are available;
  71.         // we depend on these features  
  72.         if (!QTUtils_HasQuickTimeVideoEffects())
  73.             QTFrame_QuitFramework();
  74.  
  75. #if TARGET_OS_MAC
  76.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  77.         QTApp_InstallAppleEventHandlers();
  78. #endif
  79.     }
  80.  
  81.     // do any start-up activities that should occur after the MDI frame window is created
  82.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  83. #if TARGET_OS_WIN32
  84.         // on Windows, open as movie documents any files specified on the command line
  85.         SendMessage(ghWnd, WM_OPENDROPPEDFILES, 0L, 0L);
  86. #endif
  87.     }
  88. }
  89.  
  90.  
  91. //////////
  92. //
  93. // QTApp_Stop
  94. // Do any application-specific shut-down.
  95. //
  96. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  97. // *before* any open movie windows are destroyed or *after*.
  98. //
  99. //////////
  100.  
  101. void QTApp_Stop (UInt32 theStopPhase)
  102. {    
  103.     // do any shut-down activities that should occur before the movie windows are destroyed
  104.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows) {
  105.         
  106.     }
  107.     
  108.     // do any shut-down activities that should occur after the movie windows are destroyed
  109.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  110. #if TARGET_OS_MAC
  111.         // dispose of routine descriptors for Apple event handlers
  112.         DisposeAEEventHandlerUPP(gHandleOpenAppAEUPP);
  113.         DisposeAEEventHandlerUPP(gHandleOpenDocAEUPP);
  114.         DisposeAEEventHandlerUPP(gHandlePrintDocAEUPP);
  115.         DisposeAEEventHandlerUPP(gHandleQuitAppAEUPP);
  116. #endif
  117.     
  118.     }
  119. }
  120.  
  121.  
  122. //////////
  123. //
  124. // QTApp_Idle
  125. // Do any processing that can/should occur at idle time.
  126. //
  127. //////////
  128.  
  129. void QTApp_Idle (WindowReference theWindow)
  130. {
  131.     WindowObject         myWindowObject = NULL;
  132.     GrafPtr             mySavedPort;
  133.     //Cursor                myArrow;
  134.     
  135.     GetPort(&mySavedPort);
  136.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  137.     
  138.     myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow);
  139.     if (myWindowObject != NULL) {
  140.         MovieController        myMC = NULL;
  141.     
  142.         myMC = (**myWindowObject).fController;
  143.         if (myMC != NULL) {
  144.             
  145.             // run any idle-time tasks for the movie
  146.             
  147. #if TARGET_OS_MAC
  148.             // restore the cursor to the arrow
  149.             // if it's outside the front movie window or outside the window's visible region
  150.             if (theWindow == QTFrame_GetFrontMovieWindow()) {
  151.                 Rect            myRect;
  152.                 Point            myPoint;
  153.                 RgnHandle        myVisRegion;
  154.                 Cursor            myArrow;
  155.                 
  156.                 GetMouse(&myPoint);
  157.                 myVisRegion = NewRgn();
  158.                 GetPortVisibleRegion(QTFrame_GetPortFromWindowReference(theWindow), myVisRegion);
  159.                 GetWindowPortBounds(theWindow, &myRect);
  160.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, myVisRegion))
  161.                     MacSetCursor(GetQDGlobalsArrow(&myArrow));
  162.                     
  163.                 DisposeRgn(myVisRegion);
  164.             }
  165. #endif // TARGET_OS_MAC
  166.         }
  167.     }
  168.     
  169.     // ***insert application-specific idle-time processing here***
  170.     
  171.     MacSetPort(mySavedPort);
  172. }
  173.  
  174.  
  175. //////////
  176. //
  177. // QTApp_Draw
  178. // Update the specified window.
  179. //
  180. //////////
  181.  
  182. void QTApp_Draw (WindowReference theWindow, Rect *theRefreshArea)
  183. {
  184. #pragma unused(theRefreshArea)
  185.  
  186.     GrafPtr             mySavedPort;
  187.     
  188.     GetPort(&mySavedPort);
  189.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  190.     
  191.     BeginUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  192.     //EraseRect(theRefreshArea);        // this is important only for non-rectangular movies
  193.     
  194.     // ***insert application-specific drawing here***
  195.     
  196.     // draw the movie controller and its movie
  197.     MCDoAction(QTFrame_GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  198.     
  199.     EndUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  200.     MacSetPort(mySavedPort);
  201. }
  202.  
  203.  
  204. //////////
  205. //
  206. // QTApp_HandleContentClick
  207. // Handle mouse button clicks in the specified window.
  208. //
  209. //////////
  210.  
  211. void QTApp_HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  212. {
  213. #pragma unused(theEvent)
  214.  
  215.     GrafPtr             mySavedPort;
  216.     
  217.     GetPort(&mySavedPort);
  218.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  219.     
  220.     // ***insert application-specific content-click processing here***
  221.  
  222.     MacSetPort(mySavedPort);
  223. }
  224.  
  225.  
  226. //////////
  227. //
  228. // QTApp_HandleKeyPress
  229. // Handle application-specific key presses.
  230. // Returns true if the key press was handled, false otherwise.
  231. //
  232. //////////
  233.  
  234. Boolean QTApp_HandleKeyPress (char theCharCode)
  235. {
  236.     Boolean        isHandled = true;
  237.     
  238.     switch (theCharCode) {
  239.     
  240.         // ***insert application-specific key-press processing here***
  241.  
  242.         default:
  243.             isHandled = false;
  244.             break;
  245.     }
  246.  
  247.     return(isHandled);
  248. }
  249.  
  250.  
  251. //////////
  252. //
  253. // QTApp_HandleMenu
  254. // Handle selections in the application's menus.
  255. //
  256. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  257. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window procedure.
  258. // When called from MacOS, theMenuItem is constructed like this:
  259. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  260. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  261. // In this way, we can simplify the menu-handling code. There are, however, some limitations, mainly that
  262. // the menu item identifiers on Windows must be derived from the Mac values. 
  263. //
  264. //////////
  265.  
  266. Boolean QTApp_HandleMenu (UInt16 theMenuItem)
  267. {
  268.     Boolean                myIsHandled = false;            // false => allow caller to process the menu item
  269.     
  270.     switch (theMenuItem) {
  271.     
  272.         case IDM_MAKE_EFFECT_MOVIE:
  273.             // ask the user for some movies and an effect,
  274.             // but only if the effects dialog isn't showing already
  275.             if (gEffectsDialog == 0L)
  276.                 QTEffects_PromptUserForFilesAndMakeEffect();
  277.             myIsHandled = true;
  278.             break;
  279.  
  280.         case IDM_MAKE_STANDALONE_MOVIE:
  281.             gCopyMovieMedia = true;
  282.             myIsHandled = true;
  283.             break;
  284.  
  285.         case IDM_MAKE_REFERENCED_MOVIE:
  286.             gCopyMovieMedia = false;
  287.             myIsHandled = true;
  288.             break;
  289.  
  290.         default:
  291.             break;
  292.             
  293.     } // switch (theMenuItem)
  294.     
  295.     return(myIsHandled);
  296. }
  297.  
  298.  
  299. //////////
  300. //
  301. // QTApp_AdjustMenus
  302. // Adjust state of items in the application's menus.
  303. //
  304. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  305. //
  306. //////////
  307.  
  308. void QTApp_AdjustMenus (WindowReference theWindow, MenuReference theMenu)
  309. {
  310. #if TARGET_OS_MAC
  311. #pragma unused(theMenu)
  312. #endif
  313.  
  314. #pragma unused(theWindow)
  315.     MenuReference            myMenu;
  316.     
  317. #if TARGET_OS_WIN32
  318.     myMenu = theMenu;
  319. #elif TARGET_OS_MAC
  320.     myMenu = GetMenuHandle(kTestMenuResID);
  321. #endif
  322.     
  323.     // if the effects dialog is already open, don't allow user to select more files
  324.     if (gEffectsDialog != 0)
  325.         QTFrame_SetMenuItemState(myMenu, IDM_MAKE_EFFECT_MOVIE, kDisableMenuItem);
  326.     else
  327.         QTFrame_SetMenuItemState(myMenu, IDM_MAKE_EFFECT_MOVIE, kEnableMenuItem);
  328.     
  329.     // check the current media-copying selection    
  330.     QTFrame_SetMenuItemCheck(myMenu, IDM_MAKE_STANDALONE_MOVIE, gCopyMovieMedia == true);
  331.     QTFrame_SetMenuItemCheck(myMenu, IDM_MAKE_REFERENCED_MOVIE, gCopyMovieMedia == false);
  332. }
  333.  
  334.  
  335. //////////
  336. //
  337. // QTApp_HandleEvent
  338. // Perform any application-specific event loop actions.
  339. //
  340. // Return true to indicate that we've completely handled the event here, false otherwise.
  341. //
  342. //////////
  343.  
  344. Boolean QTApp_HandleEvent (EventRecord *theEvent)
  345. {
  346.     Boolean        isHandled = false;
  347.     
  348.     // see if the event is meant for the effects parameter dialog box
  349.     if (gEffectsDialog != 0L)
  350.         isHandled = QTEffects_HandleEffectsDialogEvents(theEvent, 0);
  351.  
  352.     return(isHandled);
  353. }
  354.  
  355.  
  356. //////////
  357. //
  358. // QTApp_SetupController
  359. // Configure the movie controller.
  360. //
  361. //////////
  362.  
  363. void QTApp_SetupController (MovieController theMC)
  364. {
  365.     long            myControllerFlags;
  366.     
  367.     // CLUT table use
  368.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  369.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  370.  
  371.     // enable keyboard event handling
  372.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  373.     
  374.     // disable drag support
  375.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  376. }
  377.  
  378.  
  379. //////////
  380. //
  381. // QTApp_SetupWindowObject
  382. // Do any application-specific initialization of the window object.
  383. //
  384. //////////
  385.  
  386. void QTApp_SetupWindowObject (WindowObject theWindowObject)
  387. {
  388. #pragma unused(theWindowObject)
  389. }
  390.  
  391.  
  392. //////////
  393. //
  394. // QTApp_RemoveWindowObject
  395. // Do any application-specific clean-up of the window object.
  396. //
  397. //////////
  398.  
  399. void QTApp_RemoveWindowObject (WindowObject theWindowObject)
  400. {
  401. #pragma unused(theWindowObject)
  402.     // QTFrame_DestroyMovieWindow in MacFramework.c or QTFrame_MovieWndProc in WinFramework.c
  403.     // releases the window object itself
  404. }
  405.  
  406.  
  407. //////////
  408. //
  409. // QTApp_MCActionFilterProc 
  410. // Intercept some actions for the movie controller.
  411. //
  412. // NOTE: The theRefCon parameter is a handle to a window object record.
  413. //
  414. //////////
  415.  
  416. PASCAL_RTN Boolean QTApp_MCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  417. {
  418. #pragma unused(theMC, theParams)
  419.  
  420.     Boolean                isHandled = false;            // false => allow controller to process the action
  421.     WindowObject        myWindowObject = NULL;
  422.     
  423.     myWindowObject = (WindowObject)theRefCon;
  424.     if (myWindowObject == NULL)
  425.         return(isHandled);
  426.         
  427.     switch (theAction) {
  428.     
  429.         // handle window resizing
  430.         case mcActionControllerSizeChanged:
  431.             if (MCIsControllerAttached(theMC) == 1)
  432.                 QTFrame_SizeWindowToMovie(myWindowObject);
  433.             break;
  434.  
  435.         // handle idle events
  436.         case mcActionIdle:
  437.             QTApp_Idle((**myWindowObject).fWindow);
  438.             break;
  439.             
  440.         default:
  441.             break;
  442.             
  443.     } // switch (theAction)
  444.     
  445.     return(isHandled);    
  446. }
  447.  
  448.  
  449. #if TARGET_OS_MAC
  450. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  451. //
  452. // Apple Event functions.
  453. //
  454. // Use these functions to install handlers for Apple Events and to handle those events.
  455. //
  456. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  457.  
  458. //////////
  459. //
  460. // QTApp_InstallAppleEventHandlers 
  461. // Install handlers for Apple Events.
  462. //
  463. //////////
  464.  
  465. void QTApp_InstallAppleEventHandlers (void)
  466. {
  467.     long        myAttrs;
  468.     OSErr        myErr = noErr;
  469.     
  470.     // see whether the Apple Event Manager is available in the present operating environment;
  471.     // if it is, install handlers for the four required Apple Events
  472.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  473.     if (myErr == noErr) {
  474.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  475.             // create routine descriptors for the Apple event handlers
  476.             gHandleOpenAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenApplicationAppleEvent);
  477.             gHandleOpenDocAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenDocumentAppleEvent);
  478.             gHandlePrintDocAEUPP = NewAEEventHandlerUPP(QTApp_HandlePrintDocumentAppleEvent);
  479.             gHandleQuitAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleQuitApplicationAppleEvent);
  480.             
  481.             // install the handlers
  482.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  483.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  484.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  485.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  486.         }
  487.     }
  488. }
  489.         
  490.         
  491. //////////
  492. //
  493. // QTApp_HandleOpenApplicationAppleEvent 
  494. // Handle the open-application Apple Events.
  495. //
  496. //////////
  497.  
  498. PASCAL_RTN OSErr QTApp_HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  499. {
  500. #pragma unused(theMessage, theReply, theRefcon)
  501.     
  502.     // we don't need to do anything special when opening the application
  503.     return(noErr);
  504. }
  505.  
  506.  
  507. //////////
  508. //
  509. // QTApp_HandleOpenDocumentAppleEvent 
  510. // Handle the open-document Apple Events. This is based on Inside Macintosh: IAC, pp. 4-15f.
  511. //
  512. // Here we process an Open Documents AE only for files of type MovieFileType.
  513. //
  514. //////////
  515.  
  516. PASCAL_RTN OSErr QTApp_HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  517. {
  518. #pragma unused(theReply, theRefcon)
  519.  
  520.     long            myIndex;
  521.     long            myItemsInList;
  522.     AEKeyword        myKeyWd;
  523.     OSErr            myIgnoreErr;
  524.     AEDescList          myDocList;
  525.     long            myActualSize;
  526.     DescType        myTypeCode;
  527.     FSSpec            myFSSpec;
  528.     FSSpec            myFSSpecList[kMaxNumSources];
  529.     UInt16            myFSSpecCount = 0;
  530.     OSErr            myErr = noErr;
  531.     
  532.     // get the direct parameter and put it into myDocList
  533.     myDocList.dataHandle = NULL;
  534.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  535.     
  536.     // count the descriptor records in the list
  537.     if (myErr == noErr)
  538.         myErr = AECountItems(&myDocList, &myItemsInList);
  539.     else
  540.         myItemsInList = 0;
  541.     
  542.     // open each specified file
  543.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  544.         if (myErr == noErr) {
  545.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  546.             if ((myErr == noErr) && (myFSSpecCount < kMaxNumSources)) {
  547.                 myFSSpecList[myFSSpecCount] = myFSSpec;
  548.                 myFSSpecCount++;
  549.             }
  550.         }
  551.  
  552.     if (myDocList.dataHandle)
  553.         myIgnoreErr = AEDisposeDesc(&myDocList);
  554.     
  555.     if (myErr == noErr)
  556.         myErr = QTEffects_DisplayDialogForSources(myFSSpecList, myFSSpecCount);
  557.     
  558.     // make sure we open the document in the foreground        
  559.     gAppInForeground = true;
  560.     return(myErr);
  561. }
  562.  
  563.  
  564. //////////
  565. //
  566. // QTApp_HandlePrintDocumentAppleEvent 
  567. // Handle the print-document Apple Events.
  568. //
  569. // NOT YET IMPLEMENTED.
  570. //
  571. //////////
  572.  
  573. PASCAL_RTN OSErr QTApp_HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  574. {
  575. #pragma unused(theMessage, theReply, theRefcon)
  576.  
  577.     return(errAEEventNotHandled);
  578. }
  579.  
  580.  
  581. //////////
  582. //
  583. // QTApp_HandleQuitApplicationAppleEvent 
  584. // Handle the quit-application Apple Events.
  585. //
  586. //////////
  587.  
  588. PASCAL_RTN OSErr QTApp_HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  589. {
  590. #pragma unused(theMessage, theReply, theRefcon)
  591.  
  592.     // close down the entire framework and application
  593.     QTFrame_QuitFramework();
  594.     return(noErr);
  595. }
  596. #endif // TARGET_OS_MAC
  597.  
  598.  
  599.